package proto;

import java.awt.Color;
import java.awt.Font;
import javax.swing.*;
import proto.GeneralInput.Mode;

/**
 * Graphics class responsible for the graphical illustration of the game.
 * @author Bitjaeher
 */
public abstract class Graphics {
    private static Level level;
    private static Color[][] matrix;
    private static JFrame frame;
    private static JPanel canvas;
    private static java.awt.Graphics frameGraphics;
    private static int width = 15;
    /**
     * Create a matrix and fill it up with * characters.
     * @param lvl
     */
    public static void SetLevel(Level lvl){
        level = lvl;
        matrix = new Color[(level.GetEmptyTile().GetColumnCount() + 1) * level.GetColumnCount() - 1]
            [(level.GetEmptyTile().GetRowCount() + 1) * level.GetRowCount() - 1];
        for(int y = 0; y < matrix[0].length; y++){
            for (int x = 0; x < matrix.length; x++){
                matrix[x][y] = Color.LIGHT_GRAY;
            }
        }
    }

    public static void InitFrame(GeneralInput gi){
        frame = new JFrame("Continutiy");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(900, 600);
        frame.addKeyListener(gi);

        canvas = new JPanel(true); // Double buffering on!
        frame.add(canvas);

        JMenuItem resetMenuItem = new JMenuItem("Reset game");
            resetMenuItem.setActionCommand("reset");
            resetMenuItem.addActionListener(gi);
        JMenuItem restartMenuItem = new JMenuItem("Restart level");
            restartMenuItem.setActionCommand("restart");
            restartMenuItem.addActionListener(gi);
        JMenuItem skipMenuItem = new JMenuItem("Skip level");
            skipMenuItem.setActionCommand("skip");
            skipMenuItem.addActionListener(gi);
        JMenu gameMenu = new JMenu("Game");
        gameMenu.add(resetMenuItem);
        gameMenu.add(restartMenuItem);
        gameMenu.add(skipMenuItem);

        JMenuItem howtoMenuItem = new JMenuItem("How to play");
            howtoMenuItem.setActionCommand("howto");
            howtoMenuItem.addActionListener(gi);
        JMenuItem aboutMenuItem = new JMenuItem("About");
            aboutMenuItem.setActionCommand("about");
            aboutMenuItem.addActionListener(gi);
        JMenu helpMenu = new JMenu("Help");
        helpMenu.add(howtoMenuItem);
        helpMenu.add(aboutMenuItem);

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(gameMenu);
        menuBar.add(helpMenu);
        frame.setJMenuBar(menuBar);

        frame.setVisible(true);
        frameGraphics = canvas.getGraphics();
    }

    public static void ClearGameArea(){
        frameGraphics.clearRect(20, 124, frame.getWidth(), frame.getHeight());
    }

    /** Convert the current level state to a character array and print it.
    *
    * Drawing happens by iterating over the rows of the tiles and
    * writing their appropriate characters in a 2D matrix,
    * then simply printing this matrix.
    *
    * We start out at the upper-left tile and move to the right,
    * then go down to the second row and so on.
    */
    public static void DrawInfo(Mode mode){
        frameGraphics.clearRect(300, 5, 450, 5+20/3*2*3);
        frameGraphics.setFont(new Font("TimesRoman", Font.BOLD,  20/3*2));
        frameGraphics.setColor(Color.BLACK);
        frameGraphics.drawString(mode == Mode.PUZZLE ? "PUZZLE mode" : "STICKMAN mode",
                 305, 5+20/3*2*1);
        frameGraphics.drawString("Elapsed Time:", 305, 5+20/3*2*2);
        frameGraphics.drawString(level.getTime(), 305, 5+20/3*2*3);
    }
    public static void Draw(){
        // first is always the first tile in the current row
        Tile first = level.GetUpperLeftTile();

        Tile current = first;
        // iterate downwards over the rows until we get to null (=no tile)
        for(int tileY = 0; first != null; tileY++){
            // iterate right over the tiles in the row intil we get to null (=no tile)
            for(int tileX = 0; current != null; tileX++){
                // create a submatrix with the size a tile and fill it up
                Color[][] subMatrix = current.GetMatrix();
                // then insert it to the big matrix (magic)
                for(int y = 0; y < subMatrix[0].length; y++){
                    for (int x = 0; x < subMatrix.length; x++){
                        matrix[tileX*(current.GetColumnCount() + 1) + x]
                              [tileY*(current.GetRowCount() + 1) + y] = subMatrix[x][y];
                    }
                }
                // move right
                current = current.GetNeighbor(Direction.RIGHT);
            }
            // got to the right side end of the line: move down one row
            first = first.GetNeighbor(Direction.DOWN);
            current = first;
        }

        for(int y = 0; y < matrix[0].length; y++){
            for (int x = 0; x < matrix.length; x++){
                frameGraphics.setColor(matrix[x][y]);
                frameGraphics.fillRect(20 + width*x, 124 + width*y, width, width);
            }
        }
    }

    public static void Message(String msg) {
        JOptionPane.showMessageDialog(frame, msg);
    }
}
